 TTL Ar* Podule loader code definition => Loader

 ; Modifications:
 ;
 ; 07-Aug-87 APT  DDR setting only sets bottom 3 bits as outputs
 ; 11-Sep-87  BC  Add stuff to turn interrupts on and off
 ; 02-Nov-87  BC  Took interrupt stuff back out
 ; 07-Dec-88 SKS  Put into IO_Podule structure before leaving
 ; 05-Jul-89 TMD  Converted to new source release control
 ;
 ; All code must be relocatable and position independant.  It can be
 ; assumed that the code will be run in RAM in SVC mode.  The base
 ; address will be as if an ALIGN 16, 4 had be 'executed' before the
 ; code was assembled.
 ;
 ; Registers
 ; ---------
 ;
 ;         Input       Output     Comments
 ;         -----       ------     --------
 ; R0      Write data  Read data  Treated as a byte
 ; R1      Address                Must be preserved
 ; R2 - R4                        May be used
 ; R5 - R9                        Must be preserved
 ; R10                            May be used
 ; R11     Hardware               Base address of hardware, must be preserved 
 ; R12                            Private, must be preserved
 ; R13     sp                     Stack pointer (FD)
 ; R14                            Return address use BICS pc, lr, #V_bit
 ; R15                            PC
 ;
 ; Entry points
 ; ------------
 ; Origin + &00     Read a byte
 ; Origin + &04     Write a byte
 ; Origin + &08     Reset to initial state, if possible
 ; Origin + &0C     SWI XROMPodule_CallLoader
 ;
 ; Initialisation
 ; --------------
 ; The first call will be to Read address 0.
 ;
 ; Errors
 ; ------
 ; Read and Write may be able to return errors like 'Bad address' if the
 ; device is not as big as the address given, or 'Bad write' if using
 ; read after write checks on the Write call.  If the SWI entry is not
 ; supported then don't return an error.  If reset fails or can't be done
 ; then report an error.  Since device drivers may well be short of space
 ; it will be possible to return an error with R0=0 and an error string will
 ; be used from the Podule manager, note that this is not encouraged but is
 ; offered as a last resort.  Errors ar returned to the caller by using
 ; ORRS pc, lr, #V_bit rather than the usual BICS exit.
 ;
 ; Example
 ; -------

 SUBT Podule loader for Archimedes BBC I/O podule

 GET <urd>.Hdr.ListOpts
 GET <urd>.Hdr.Macros
 GET <urd>.Hdr.System
 GET <urd>.Hdr.ModHand
 GET <urd>.Hdr.NewErrors
 GET <urd>.Hdr.Podule

 GET <dir>.IO_Podule.LdrVersion

 LEADR &FFFFFD00 ; Data

VIA * &2000
DataRegister * &2004
DirectionRegister * &200C 
PCRegister * &2030

PageSize * 11 ; Bits

Origin
 B ReadByte
 B WriteByte
 B Reset
 BICS pc, lr, #V_bit

Page ; Variable
 DCD -1

Reset
 LDR r10, =Podule_BaseAddressANDMask
 AND r10, r11, r10 ; Hardware address only
 ADD r10, r10, #VIA
 MOV r2, #-1
 STR r2, Page
 MOV r2, #0 ; All inputs, so selecting default page
 STRB r2, [ r10, #DirectionRegister - VIA ]
 BICS pc, lr, #V_bit

ReadByte
 LDR r4, =Podule_BaseAddressANDMask
 AND r4, r11, r4 ; Hardware address only
 ADD r10, r4, #VIA
 MOV r2, #2_00000111 ; Set the bottom lines as output - Sam sez only bottom 3
                     ; as bit 3 is connected to pin 1 (Vpp) on 27128 -> 0 no good
 STRB r2, [ r10, #DirectionRegister - VIA ]
 CMP r1, #&F800 ; Last page
 ADRHS Error, ErrorBlock_AddressTooBig
 ORRHSS pc, lr, #V_bit
 MOV r2, r1, ASR #PageSize
 LDR r3, Page
 TEQ r2, r3
 STRNEB r2, [ r10, #DataRegister - VIA ]
 STRNE r2, Page
 SUB r2, r1, r2, ASL #PageSize
 LDRB r0, [ r4, r2, ASL #2 ] ; Account for word addressing
 BICS pc, lr, #V_bit

WriteByte
 ADR Error, ErrorBlock_NotWriteable
 ORRS pc, lr, #V_bit

 MakeErrorBlock NotWriteable
 MakeErrorBlock AddressTooBig

VersionString
 DCB "BBCIOBoardLoader", 9, "$Version ($CurrentDate)", 0

 END
